----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    14:57:35 08/12/2015 
-- Design Name: 
-- Module Name:    shift_register - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity shift_register is
    Port ( clk : in  STD_LOGIC;
           en_input : in  STD_LOGIC;
           en_output : in  STD_LOGIC;
           din : in  STD_LOGIC_VECTOR (31 downto 0);
           dout : out  STD_LOGIC);
end shift_register;

architecture Behavioral of shift_register is
	signal dout_signal : STD_LOGIC := '0';
	signal dregister : STD_LOGIC_VECTOR (31 downto 0) := (others => '0');
	signal cregister : STD_LOGIC_VECTOR ( 3 downto 0) := (others => '0');
	signal out_cnt : integer := 0;
	signal chk_cnt : integer := 0;
begin

process(clk, en_input, din)
begin
	if (en_input='1') then
		dregister <= din;
		cregister <= (others=>'0');
		out_cnt <= 0;
		chk_cnt <= 3;
	elsif (clk'event and clk='1' and en_output='1') then
		if (out_cnt = 36) then
			out_cnt <= 0;
			dout_signal <= dregister(31);
			dregister <= dregister(30 downto 0) & '0';
		elsif (out_cnt < 32) then
			out_cnt <= out_cnt + 1;
			dout_signal <= dregister(31);
			cregister(chk_cnt) <= cregister(chk_cnt) xor dregister(31);
			dregister <= dregister(30 downto 0) & '0';
			if (chk_cnt = 0) then
				chk_cnt <= 3;
			else
				chk_cnt <= chk_cnt - 1;
			end if;
		elsif (out_cnt < 36) then
			out_cnt <= out_cnt + 1;
			dout_signal <= cregister(3);
			cregister <= cregister(2 downto 0) & '0';
		end if;
	end if;
end process;

dout <= dout_signal;

end Behavioral;

